#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
工单管理专项测试脚本

专门测试调度系统的工单管理功能，包括：
- 工单CRUD操作
- 自定义字段管理
- 工单状态流转
- 处理记录管理
- 工单统计
- 权限控制

使用方法：
python work_order_test.py
"""

import requests
import json
import time
from datetime import datetime, timedelta

# 配置
BASE_URL = "http://localhost:5000/api"
TEST_USERNAME = "admin"
TEST_PASSWORD = "admin123"

class WorkOrderTester:
    def __init__(self, base_url=BASE_URL):
        self.base_url = base_url
        self.session = requests.Session()
        self.token = None
        self.test_data = {
            'created_orders': [],
            'created_fields': []
        }
        
    def login(self):
        """登录获取Token"""
        url = f"{self.base_url}/auth/login"
        data = {
            "username": TEST_USERNAME,
            "password": TEST_PASSWORD
        }
        
        try:
            response = self.session.post(url, json=data)
            if response.status_code == 200:
                result = response.json()
                self.token = result['access_token']
                print(f"✓ 登录成功: {result['user']['name']}")
                return True
            else:
                print(f"✗ 登录失败: {response.text}")
                return False
        except Exception as e:
            print(f"✗ 登录异常: {e}")
            return False
    
    def make_request(self, method, endpoint, data=None, params=None):
        """发送HTTP请求"""
        url = f"{self.base_url}{endpoint}"
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.token}"
        }
        
        try:
            if method.upper() == "GET":
                response = self.session.get(url, headers=headers, params=params)
            elif method.upper() == "POST":
                response = self.session.post(url, headers=headers, json=data)
            elif method.upper() == "PUT":
                response = self.session.put(url, headers=headers, json=data)
            elif method.upper() == "DELETE":
                response = self.session.delete(url, headers=headers)
            else:
                raise ValueError(f"Unsupported method: {method}")
                
            return response
        except Exception as e:
            print(f"Request failed: {e}")
            raise
    
    def test_work_order_crud(self):
        """测试工单CRUD操作"""
        print("\n=== 工单CRUD操作测试 ===")
        
        # 1. 创建工单
        print("\n1. 测试创建工单")
        order_data = {
            "title": f"测试工单_{int(time.time())}",
            "description": "这是一个详细的测试工单描述，用于验证工单创建功能。",
            "type": "maintenance",
            "priority": "high",
            "location": "测试地点A区域",
            "notes": "重要：这是测试工单，请勿实际执行",
            "scheduled_start": (datetime.now() + timedelta(days=1)).isoformat(),
            "scheduled_end": (datetime.now() + timedelta(days=2)).isoformat()
        }
        
        response = self.make_request("POST", "/work_orders", order_data)
        if response.status_code == 201:
            created_order = response.json()['work_order']
            order_id = created_order['id']
            self.test_data['created_orders'].append(order_id)
            print(f"✓ 工单创建成功: ID={order_id}, 编号={created_order['order_number']}")
        else:
            print(f"✗ 工单创建失败: {response.text}")
            return False
        
        # 2. 获取工单详情
        print("\n2. 测试获取工单详情")
        response = self.make_request("GET", f"/work_orders/{order_id}")
        if response.status_code == 200:
            order_detail = response.json()['work_order']
            print(f"✓ 工单详情获取成功: {order_detail['title']}")
            print(f"  状态: {order_detail['status']}")
            print(f"  优先级: {order_detail['priority']}")
            print(f"  创建时间: {order_detail['created_at']}")
        else:
            print(f"✗ 获取工单详情失败: {response.text}")
        
        # 3. 更新工单
        print("\n3. 测试更新工单")
        update_data = {
            "status": "in_progress",
            "priority": "urgent",
            "notes": "更新：工单已开始处理，优先级提升为紧急",
            "actual_start": datetime.now().isoformat()
        }
        
        response = self.make_request("PUT", f"/work_orders/{order_id}", update_data)
        if response.status_code == 200:
            updated_order = response.json()['work_order']
            print(f"✓ 工单更新成功")
            print(f"  新状态: {updated_order['status']}")
            print(f"  新优先级: {updated_order['priority']}")
        else:
            print(f"✗ 工单更新失败: {response.text}")
        
        # 4. 获取工单列表
        print("\n4. 测试获取工单列表")
        params = {
            "page": 1,
            "per_page": 10,
            "status": "in_progress"
        }
        response = self.make_request("GET", "/work_orders", params=params)
        if response.status_code == 200:
            orders_data = response.json()
            print(f"✓ 工单列表获取成功: 共{orders_data['total']}个工单")
            print(f"  当前页: {orders_data['current_page']}/{orders_data['pages']}")
        else:
            print(f"✗ 获取工单列表失败: {response.text}")
        
        return True
    
    def test_custom_fields(self):
        """测试自定义字段功能"""
        print("\n=== 自定义字段测试 ===")
        
        # 1. 获取现有字段
        print("\n1. 获取现有自定义字段")
        response = self.make_request("GET", "/work_orders/fields")
        if response.status_code == 200:
            fields_data = response.json()
            print(f"✓ 获取到 {len(fields_data.get('fields', []))} 个自定义字段")
        else:
            print(f"✗ 获取自定义字段失败: {response.text}")
        
        # 2. 创建文本字段
        print("\n2. 创建文本类型字段")
        text_field_data = {
            "name": f"test_text_field_{int(time.time())}",
            "label": "测试文本字段",
            "field_type": "text",
            "is_required": False,
            "default_value": "默认文本值"
        }
        
        response = self.make_request("POST", "/work_orders/fields", text_field_data)
        if response.status_code == 201:
            text_field = response.json()['field']
            text_field_id = text_field['id']
            self.test_data['created_fields'].append(text_field_id)
            print(f"✓ 文本字段创建成功: ID={text_field_id}")
        else:
            print(f"✗ 文本字段创建失败: {response.text}")
            return False
        
        # 3. 创建选择字段
        print("\n3. 创建选择类型字段")
        select_field_data = {
            "name": f"test_select_field_{int(time.time())}",
            "label": "测试选择字段",
            "field_type": "select",
            "options": json.dumps(["选项1", "选项2", "选项3"], ensure_ascii=False),
            "is_required": True
        }
        
        response = self.make_request("POST", "/work_orders/fields", select_field_data)
        if response.status_code == 201:
            select_field = response.json()['field']
            select_field_id = select_field['id']
            self.test_data['created_fields'].append(select_field_id)
            print(f"✓ 选择字段创建成功: ID={select_field_id}")
        else:
            print(f"✗ 选择字段创建失败: {response.text}")
        
        # 4. 创建多选字段
        print("\n4. 创建多选类型字段")
        checkbox_field_data = {
            "name": f"test_checkbox_field_{int(time.time())}",
            "label": "测试多选字段",
            "field_type": "checkbox",
            "options": json.dumps(["多选项1", "多选项2", "多选项3", "多选项4"], ensure_ascii=False),
            "is_required": False
        }
        
        response = self.make_request("POST", "/work_orders/fields", checkbox_field_data)
        if response.status_code == 201:
            checkbox_field = response.json()['field']
            checkbox_field_id = checkbox_field['id']
            self.test_data['created_fields'].append(checkbox_field_id)
            print(f"✓ 多选字段创建成功: ID={checkbox_field_id}")
        else:
            print(f"✗ 多选字段创建失败: {response.text}")
        
        # 5. 更新字段
        print("\n5. 测试更新字段")
        update_field_data = {
            "label": "更新后的测试文本字段",
            "default_value": "更新后的默认值"
        }
        
        response = self.make_request("PUT", f"/work_orders/fields/{text_field_id}", update_field_data)
        if response.status_code == 200:
            print(f"✓ 字段更新成功")
        else:
            print(f"✗ 字段更新失败: {response.text}")
        
        return True
    
    def test_work_order_with_custom_fields(self):
        """测试带自定义字段的工单"""
        print("\n=== 带自定义字段的工单测试 ===")
        
        # 创建带自定义字段值的工单
        print("\n1. 创建带自定义字段的工单")
        order_data = {
            "title": f"带自定义字段的测试工单_{int(time.time())}",
            "description": "测试自定义字段功能的工单",
            "type": "maintenance",
            "priority": "medium",
            "custom_fields": {
                "test_text_field": "自定义文本值",
                "test_select_field": "选项2",
                "test_checkbox_field": ["多选项1", "多选项3"]
            }
        }
        
        response = self.make_request("POST", "/work_orders", order_data)
        if response.status_code == 201:
            created_order = response.json()['work_order']
            order_id = created_order['id']
            self.test_data['created_orders'].append(order_id)
            print(f"✓ 带自定义字段的工单创建成功: ID={order_id}")
            
            # 验证自定义字段值
            if 'custom_fields' in created_order:
                print("  自定义字段值:")
                for field_name, field_data in created_order['custom_fields'].items():
                    print(f"    {field_data['label']}: {field_data['value']}")
        else:
            print(f"✗ 带自定义字段的工单创建失败: {response.text}")
            return False
        
        # 更新自定义字段值
        print("\n2. 更新工单自定义字段")
        update_data = {
            "custom_fields": {
                "test_text_field": "更新后的文本值",
                "test_checkbox_field": ["多选项2", "多选项4"]
            }
        }
        
        response = self.make_request("PUT", f"/work_orders/{order_id}", update_data)
        if response.status_code == 200:
            print(f"✓ 自定义字段更新成功")
        else:
            print(f"✗ 自定义字段更新失败: {response.text}")
        
        return True
    
    def test_process_records(self):
        """测试处理记录功能"""
        print("\n=== 处理记录测试 ===")
        
        if not self.test_data['created_orders']:
            print("✗ 没有可用的测试工单")
            return False
        
        order_id = self.test_data['created_orders'][0]
        
        # 1. 添加处理记录
        print("\n1. 添加处理记录")
        records_to_add = [
            {"action": "接收工单", "description": "工单已接收，开始分析问题"},
            {"action": "现场勘查", "description": "已到达现场，正在勘查具体情况"},
            {"action": "开始维修", "description": "问题确认，开始进行维修作业"},
            {"action": "测试验证", "description": "维修完成，正在进行功能测试"}
        ]
        
        for record_data in records_to_add:
            response = self.make_request("POST", f"/work_orders/{order_id}/records", record_data)
            if response.status_code == 201:
                print(f"✓ 处理记录添加成功: {record_data['action']}")
            else:
                print(f"✗ 处理记录添加失败: {response.text}")
            time.sleep(0.1)  # 避免时间戳相同
        
        # 2. 获取处理记录
        print("\n2. 获取处理记录列表")
        response = self.make_request("GET", f"/work_orders/{order_id}/records")
        if response.status_code == 200:
            records_data = response.json()
            records = records_data.get('records', [])
            print(f"✓ 获取到 {len(records)} 条处理记录")
            
            for i, record in enumerate(records[-3:], 1):  # 显示最后3条
                print(f"  {i}. {record['action']}: {record['description']}")
                print(f"     操作人: {record['operator']}, 时间: {record['created_at']}")
        else:
            print(f"✗ 获取处理记录失败: {response.text}")
        
        return True
    
    def test_work_order_stats(self):
        """测试工单统计功能"""
        print("\n=== 工单统计测试 ===")
        
        response = self.make_request("GET", "/work_orders/stats")
        if response.status_code == 200:
            stats_data = response.json()
            print(f"✓ 工单统计获取成功")
            print(f"  总工单数: {stats_data.get('total_orders', 0)}")
            print(f"  待处理: {stats_data.get('pending_orders', 0)}")
            print(f"  处理中: {stats_data.get('in_progress_orders', 0)}")
            print(f"  已完成: {stats_data.get('completed_orders', 0)}")
            
            if 'priority_stats' in stats_data:
                print("  优先级分布:")
                for priority, count in stats_data['priority_stats'].items():
                    print(f"    {priority}: {count}")
        else:
            print(f"✗ 工单统计获取失败: {response.text}")
        
        return True
    
    def test_work_order_search_filter(self):
        """测试工单搜索和过滤功能"""
        print("\n=== 工单搜索过滤测试 ===")
        
        # 1. 按状态过滤
        print("\n1. 按状态过滤工单")
        for status in ['pending', 'in_progress', 'completed']:
            params = {'status': status, 'per_page': 5}
            response = self.make_request("GET", "/work_orders", params=params)
            if response.status_code == 200:
                data = response.json()
                print(f"✓ 状态'{status}'的工单: {data['total']}个")
            else:
                print(f"✗ 状态过滤失败: {response.text}")
        
        # 2. 按优先级过滤
        print("\n2. 按优先级过滤工单")
        for priority in ['low', 'medium', 'high', 'urgent']:
            params = {'priority': priority, 'per_page': 5}
            response = self.make_request("GET", "/work_orders", params=params)
            if response.status_code == 200:
                data = response.json()
                print(f"✓ 优先级'{priority}'的工单: {data['total']}个")
            else:
                print(f"✗ 优先级过滤失败: {response.text}")
        
        # 3. 关键词搜索
        print("\n3. 关键词搜索工单")
        search_terms = ['测试', 'maintenance', '工单']
        for term in search_terms:
            params = {'search': term, 'per_page': 5}
            response = self.make_request("GET", "/work_orders", params=params)
            if response.status_code == 200:
                data = response.json()
                print(f"✓ 搜索'{term}': {data['total']}个结果")
            else:
                print(f"✗ 搜索失败: {response.text}")
        
        return True
    
    def cleanup_test_data(self):
        """清理测试数据"""
        print("\n=== 清理测试数据 ===")
        
        # 删除测试工单
        for order_id in self.test_data['created_orders']:
            response = self.make_request("DELETE", f"/work_orders/{order_id}")
            if response.status_code == 200:
                print(f"✓ 工单 {order_id} 删除成功")
            else:
                print(f"✗ 工单 {order_id} 删除失败: {response.text}")
        
        # 删除测试字段
        for field_id in self.test_data['created_fields']:
            response = self.make_request("DELETE", f"/work_orders/fields/{field_id}")
            if response.status_code == 200:
                print(f"✓ 字段 {field_id} 删除成功")
            else:
                print(f"✗ 字段 {field_id} 删除失败: {response.text}")
    
    def run_all_tests(self):
        """运行所有测试"""
        print("开始工单管理专项测试...")
        print(f"测试目标: {self.base_url}")
        print("=" * 50)
        
        # 登录
        if not self.login():
            print("登录失败，停止测试")
            return
        
        test_results = []
        
        try:
            # 运行各项测试
            test_results.append(("工单CRUD操作", self.test_work_order_crud()))
            test_results.append(("自定义字段管理", self.test_custom_fields()))
            test_results.append(("带自定义字段的工单", self.test_work_order_with_custom_fields()))
            test_results.append(("处理记录管理", self.test_process_records()))
            test_results.append(("工单统计", self.test_work_order_stats()))
            test_results.append(("搜索过滤功能", self.test_work_order_search_filter()))
            
        except Exception as e:
            print(f"测试过程中发生错误: {e}")
        
        finally:
            # 清理测试数据
            self.cleanup_test_data()
        
        # 输出测试结果
        print("\n" + "=" * 50)
        print("工单管理测试结果汇总:")
        
        passed = sum(1 for _, result in test_results if result)
        total = len(test_results)
        
        for test_name, result in test_results:
            status = "✓" if result else "✗"
            print(f"{status} {test_name}")
        
        print(f"\n总测试数: {total}")
        print(f"通过: {passed}")
        print(f"失败: {total - passed}")
        print(f"成功率: {(passed/total*100):.1f}%")
        
        if passed == total:
            print("\n🎉 所有工单管理测试通过！")
        else:
            print(f"\n⚠️  有 {total - passed} 个测试失败")

def main():
    """主函数"""
    print("调度系统工单管理专项测试")
    print("=" * 30)
    
    tester = WorkOrderTester()
    tester.run_all_tests()

if __name__ == "__main__":
    main()